package cn.com.oidreams.common.utils;


import cn.com.oidreams.common.enums.ICommonEnum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author qing.yh
 * @create 2020-08-20 8:45
 * @description 描述
 */
public class EnumUtil {

    /**
     * 根据给定code获取Value
     * @param clzs  枚举类(该枚举类必须实现ICommonEnum接口)
     * @param code 枚举code
     * @return String 枚举Value
     * */
    public static String getValueByCode(Class< ? extends ICommonEnum> clzs, Object code){
        if(StringUtil.isEmpty(code)){return null;}
        ICommonEnum[] commonEnums=getICommonEnums(clzs);
        if(null==commonEnums) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(ienum.getCode().equals(String.valueOf(code))){
                return ienum.getValue();
            }
        }
        return null;
    }

    /**
     * 根据给定value获取Value
     * @param clzs  枚举类(该枚举类必须实现ICommonEnum接口)
     * @param key 枚举key
     * @return String 枚举Value
     * */
    public static String getValueByKey(Class<? extends ICommonEnum> clzs,Integer key){
        ICommonEnum[] commonEnums=getICommonEnums(clzs);
        if(null==commonEnums) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(ienum.getKey().intValue()==key.intValue()){
                return ienum.getValue();
            }
        }
        return null;
    }

    /**
     * <p>根据给定key获取value</p>
     * @param clzs 枚举类
     * @param key 枚举key
     * @return 枚举value
     * */
    public static String getValueByKey(String clzs,Integer key){
        try {
            return getValueByKey((Class<? extends ICommonEnum>) Class.forName(clzs), key);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * <p>根据给定key查询对应的枚举对象</p>
     * @param clzs 枚举类
     * @param key  枚举key
     * @return
     * */
    public static <T extends ICommonEnum> T getEnumByKey(Class<? extends ICommonEnum> clzs,Integer key){
        T[] commonEnums=getICommonEnums(clzs);
        if(null==commonEnums) {return null;}
        if(null==key){return null;}
        for(T ienum:commonEnums){
            if(null!=ienum.getKey() && ienum.getKey().intValue()==key.intValue()){
                return ienum;
            }
        }
        return null;
    }
    /**
     * <p>根据给定key查询对应的枚举对象</p>
     * @param className 类全名称(包名+类名)
     * @param key  枚举key
     * @return
     * */
    public static <T extends ICommonEnum> T getEnumByKey(String className,Integer key){
        try {
            return getEnumByKey((Class<? extends ICommonEnum>) Class.forName(className),key);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("入参传入有误!");
        }
    }

    /**
     * <p>根据给定 code 查询对应的枚举对象</p>
     * @param clz  枚举类
     * @param code 编码
     * @return
     * */
    public static <T extends ICommonEnum>T getEnumByCode(Class<? extends ICommonEnum> clz,String code){
        ICommonEnum[] commonEnums=getICommonEnums(clz);
        if(null==commonEnums|| StringUtil.isEmpty(code)) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(code.equals(ienum.getCode())){
                return (T) ienum;
            }
        }
        return null;
    }

    /**
     * <p>根据给定 code 查询对应的枚举对象</p>
     * @param clz  枚举类
     * @param value 值
     * @return
     * */
    public static <T extends ICommonEnum> T getEnumByValue(Class<? extends ICommonEnum> clz,String value){
        ICommonEnum[] commonEnums=getICommonEnums(clz);
        if(null==commonEnums||StringUtil.isEmpty(value)) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(value.equals(ienum.getValue())){
                return (T) ienum;
            }
        }
        return null;
    }

    /**
     * <p>根据给定 code 查询对应的枚举对象</p>
     * @param className  类全名称(包名+类名)
     * @param code 编码
     * @return
     * */
    public static <T extends ICommonEnum>T getEnumByCode(String className,String code){
        try {
            return getEnumByCode((Class<? extends ICommonEnum>) Class.forName(className),code);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("入参传入有误!");
        }
    }

    /**
     * <P>查询指定枚举code是否存在</P>
     * @param clz
     * @param code
     * @return
     * */
    public static boolean existByCode(Class<? extends ICommonEnum> clz,String code){
        ICommonEnum iCommonEnum = getEnumByCode(clz,code);
        if(null==iCommonEnum){return Boolean.FALSE;}
        return Boolean.TRUE;
    }
    public static boolean existByKey(Class<? extends ICommonEnum> clz,Integer key){
        ICommonEnum iCommonEnum = getEnumByKey(clz,key);
        if(null==iCommonEnum){return Boolean.FALSE;}
        return Boolean.TRUE;
    }

    /**
     * 根据给定Valuee获取code
     * @param clzs  枚举类 (该枚举类必须实现ICommonEnum接口)
     * @param value 枚举value
     * @return String 枚举code
     * */
    public static String getCodeByValue(Class<? extends ICommonEnum> clzs,String value){
        ICommonEnum[] commonEnums=getICommonEnums(clzs);
        if(null==commonEnums) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(ienum.getValue().equals(value)){
                return ienum.getCode();
            }
        }
        return null;
    }

    /**
     * 根据给定Value获取code
     * @param clzs  枚举类 (该枚举类必须实现ICommonEnum接口)
     * @param key 枚举key
     * @return String 枚举code
     * */
    public static String getCodeByKey(Class<? extends ICommonEnum> clzs,Integer key){
        ICommonEnum[] commonEnums=getICommonEnums(clzs);
        if(null==commonEnums) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(ienum.getKey().equals(key)){
                return ienum.getCode();
            }
        }
        return null;
    }

    /**
     * 根据给定code获取key
     * @param clzs  枚举类 (该枚举类必须实现ICommonEnum接口)
     * @param code  枚举code
     * @return String 枚举key
     * */
    public static Integer getKeyByCode(Class<? extends ICommonEnum> clzs,String code){
        ICommonEnum[] commonEnums=getICommonEnums(clzs);
        if(null==commonEnums) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(ienum.getCode().equals(code)){
                return ienum.getKey();
            }
        }
        return null;
    }

    /**
     * 根据给定value获取key
     * @param clzs  枚举类 (该枚举类必须实现ICommonEnum接口)
     * @param value 枚举value
     * @return String 枚举key
     * */
    public static Integer getKeyByValue(Class<? extends ICommonEnum> clzs,String value){
        ICommonEnum[] commonEnums=getICommonEnums(clzs);
        if(null==commonEnums) {return null;}
        for(ICommonEnum ienum:commonEnums){
            if(ienum.getValue().equals(value)){
                return ienum.getKey();
            }
        }
        return null;
    }

    public static Map<String,Object> getCodeValueByClz(Class<? extends ICommonEnum> clzs){
        ICommonEnum[] enums=getICommonEnums(clzs);
        Map<String,Object> map=new HashMap<String,Object>();
        for(ICommonEnum em:enums){
            map.put(em.getCode(),em.getValue());
        }
        return map;
    }

    public static Map<String,Object> getNameCodeByClz(Class<? extends ICommonEnum> clz){
        if(null==clz){return null;}
        ICommonEnum[] enums=getICommonEnums(clz);
        Map<String,Object> map=new HashMap<String,Object>();
        for(ICommonEnum em:enums){
            if(em instanceof Enum){
                map.put(((Enum)em).name(),em.getCode());
            }
        }
        return map;
    }

    /**
     * <p>根据给定枚举类得到该枚举类所有的keys集合</p>
     * @param clzs
     * @return
     * */
    public static List<Integer> getKeysByClz(Class<? extends ICommonEnum> clzs){
        ICommonEnum[] enums=getICommonEnums(clzs);
        List<Integer> result=new ArrayList<Integer>();
        for(ICommonEnum em:enums){
            result.add(em.getKey());
        }
        return result;
    }

    //----------------------------->  private method <-----------------------------

    public static <T extends ICommonEnum>T[] getICommonEnums(Class<? extends ICommonEnum> clzs){
        T[] commonEnums=null;
        try {
            commonEnums=(T[]) getEnumConstants(clzs);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return commonEnums;
    }
    private static Object[] getEnumConstants(Class<?> clzs){
        Object[] objs=null;
        if(clzs.isEnum()){
            objs=clzs.getEnumConstants();
        }
        return objs;
    }

}
